﻿using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace Innovator
{
	public static class Engine
	{
		public static GraphicsDevice GraphicsDevice;
		public static SpriteBatch SpriteBatch;
		public static GameScreenCollection GameScreens = new GameScreenCollection();
		public static GameTime GameTime;
		public static IEServiceContainer Services;
		public static IEContentManager Content;
		public static bool IsInitialized = false;
		public static GameScreen BackgroundScreen;
		public static GameScreen DefaultScreen;
		//initialize the engine
		public static void SetupEngine(IGraphicsDeviceService GraphicsDeviceService)
		{
			//setup graphicsDevice and spriteBatch
			Engine.GraphicsDevice = GraphicsDeviceService.GraphicsDevice;
			Engine.SpriteBatch = new SpriteBatch(GraphicsDeviceService.GraphicsDevice);
			Engine.Services = new IEServiceContainer();
			Engine.Services.AddService(typeof(IGraphicsDeviceService), GraphicsDeviceService);
			Engine.Content = new IEContentManager(Services);
			BackgroundScreen = new GameScreen("Engine.BackgroundScreen");
			BackgroundScreen.OverrideUpdateBlocked = true;
			BackgroundScreen.OverrideDrawBlocked = true;
			BackgroundScreen.OverrideInputBlocked = true;
			DefaultScreen = BackgroundScreen;
			Engine.IsInitialized = true;
		}
		public static void Update(GameTime gameTime)
		{
			Engine.GameTime = gameTime;
			//temp list
			List<GameScreen> updating = new List<GameScreen>();
			foreach (GameScreen screen in GameScreens)
				updating.Add(screen);
			//blocksupdate and overrideupdateblocked login?
			for (int i = GameScreens.Count - 1; i >= 0; i--)
				if (GameScreens[i].BlocksUpdate)
				{
					if (i > 0)
						for (int j = i - 1; j >= 0; j--)
							if (!GameScreens[j].OverrideUpdateBlocked)
								updating.Remove(GameScreens[j]);
					break;
				}
			//update remaining components
			foreach (GameScreen screen in updating)
				if (screen.Initialized)
					screen.Update();
			updating.Clear();
			//repopulate list
			foreach (GameScreen screen in GameScreens)
				updating.Add(screen);
			//blocksinput and overrideinputblocked login
			for(int i=GameScreens.Count -1;i>=0;i--)
				if (GameScreens[i].BlocksInput)
				{
					if (i > 0)
						for (int j = i - 1; j >= 0; j--)
							if (!GameScreens[j].OverrideInputBlocked)
								updating.Remove(GameScreens[j]);
					break;
				}
			//set isinputallowed for all gamescreens
			foreach (GameScreen screen in GameScreens)
				if (!screen.InputDisabled)
					screen.IsInputAllowed = updating.Contains(screen);
				else
					screen.IsInputAllowed = false;
		}
		public static void Draw(GameTime gameTime, ComponentType RenderType)
		{
			//update time, temp list
			Engine.GameTime = gameTime;
			List<GameScreen> drawing = new List<GameScreen>();
			//clear back buffer
			GraphicsDevice.Clear(Color.CornflowerBlue);
			//populate temp list if visible
			foreach (GameScreen screen in GameScreens)
				if (screen.Visible)
					drawing.Add(screen);
			//blocksdraw and overridedrawblocked logic
			for(int i = GameScreens.Count -1;i>=0;i--)
				if (GameScreens[i].BlocksDraw)
				{
					if (i > 0)
						for (int j = i - 1; j >= 0; j--)
							if (!GameScreens[j].OverrideDrawBlocked)
								drawing.Remove(GameScreens[j]);
					break;
				}
			//draw remaining screens
			foreach (GameScreen screen in drawing)
				if (screen.Initialized)
					screen.Draw(RenderType);
		}
	}
}